package drds.global_transaction.image.image_praser;

import drds.common.Author;
import drds.global_transaction.Authors;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.util.TablesNamesFinder;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

@Author(name = Authors.LI_YANG)
public class SqlPraser
{


    public static String tableName(String sql) throws JSQLParserException
    {

        if (insert(sql))
            return insertSentenceTableName(sql);
        else if (update(sql))
        {
            return updateSentenceTableName(sql);
        } else if (delete(sql))
        {
            return deleteSentenceTableName(sql);
        } else if (select(sql))
        {
            return selectSentenceTableName(sql);
        } else
        {
            return null;
        }

    }

    public static boolean insert(String sql)
    {
        return sql.toLowerCase().trim().startsWith("insert");
    }

    public static boolean update(String sql)
    {
        return sql.toLowerCase().trim().startsWith("update");
    }

    public static boolean delete(String sql)
    {
        return sql.toLowerCase().trim().startsWith("delete");
    }

    public static boolean select(String sql)
    {
        return sql.toLowerCase().trim().startsWith("select");
    }

    public static boolean crud(String sql)
    {
        return insert(sql) || update(sql) || delete(sql) || select(sql);
    }

    //
    public static String insertSentenceTableName(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Insert insert = (Insert) statement;
        return insert.getTable().getName();
    }

    public static List<String> insertSentenceColumnNameList(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Insert insert = (Insert) statement;
        List<Column> columnList = insert.getColumns();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < columnList.size(); i++)
        {
            list.add(columnList.get(i).toString());
        }
        return list;
    }

    public static List<String> insertSentenceColumnValueList(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Insert insert = (Insert) statement;
        List<Expression> expressionList = ((ExpressionList) insert.getItemsList()).getExpressions();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < expressionList.size(); i++)
        {
            list.add(expressionList.get(i).toString());
        }
        return list;
    }

    //
    public static String updateSentenceTableName(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Update update = (Update) statement;
        List<Table> tableList = update.getTables();
        List<String> list = new ArrayList<>();
        if (tableList != null)
        {
            for (int i = 0; i < tableList.size(); i++)
            {
                list.add(tableList.get(i).toString());
            }
        }
        return list.get(0);

    }

    public static List<String> updateSentenceColumnNameList(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Update update = (Update) statement;
        List<Column> columnList = update.getColumns();
        List<String> list = new ArrayList<>();
        if (columnList != null)
        {
            for (int i = 0; i < columnList.size(); i++)
            {
                list.add(columnList.get(i).toString());
            }
        }
        return list;

    }

    public static String updateSentenceWhereCondition(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Update update = (Update) statement;
        Expression where = update.getWhere();
        if (where == null)
        {
            return null;
        }
        return where.toString();
    }

    //
    public static String deleteSentenceTableName(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Delete delete = (Delete) statement;
        Table table = delete.getTable();
        List<String> list = new ArrayList<>();
        if (table != null)
        {
            list.add(table.toString());
        }
        return list.get(0);

    }

    public static String deleteSentenceWhereCondition(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Delete delete = (Delete) statement;
        Expression where = delete.getWhere();
        if (where == null)
        {
            return null;
        }
        return where.toString();
    }

    //
    public static String selectSentenceTableName(String sql) throws JSQLParserException
    {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Select select = (Select) statement;
        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
        List<String> list = tablesNamesFinder.getTableList(select);
        return list.get(0);
    }

    public static String selectSentenceWhereCondition(String sql) throws JSQLParserException
    {
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        Select select = (Select) parserManager.parse(new StringReader(sql));
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
        Expression where = plainSelect.getWhere();
        if (where == null)
        {
            return null;
        }
        return where.toString();
    }


}
